/*
 * @Author: 李无敌
 * @Date: 2025-01-27 10:00:00
 * @LastEditors: 李无敌
 * @LastEditTime: 2025-08-11 11:07:12
 * @FilePath: \nest-base\src\common\middleware\csp-report.middleware.ts
 * @Description: CSP违规报告中间件 (Fastify版本)
 */

import { Injectable, Logger } from '@nestjs/common';
import { FastifyRequest, FastifyReply } from 'fastify';

export interface CSPViolationReport {
  'csp-report': {
    'document-uri': string;
    'referrer': string;
    'violated-directive': string;
    'original-policy': string;
    'blocked-uri': string;
    'source-file'?: string;
    'line-number'?: number;
    'column-number'?: number;
    'status-code'?: number;
  };
}

@Injectable()
export class CSPReportMiddleware {
  private readonly logger = new Logger(CSPReportMiddleware.name);

  /**
   * 处理CSP违规报告
   */
  async handleCSPReport(request: FastifyRequest, reply: FastifyReply) {
    try {
      const report: CSPViolationReport = request.body as any;
      
      if (report && report['csp-report']) {
        const violation = report['csp-report'];
        
        // 记录CSP违规
        this.logger.warn('CSP违规检测', {
          documentUri: violation['document-uri'],
          violatedDirective: violation['violated-directive'],
          blockedUri: violation['blocked-uri'],
          sourceFile: violation['source-file'],
          lineNumber: violation['line-number'],
          columnNumber: violation['column-number'],
          userAgent: request.headers['user-agent'],
          ip: request.ip || request.socket.remoteAddress,
          timestamp: new Date().toISOString()
        });

        // 可以在这里添加更多处理逻辑，比如：
        // - 发送告警通知
        // - 存储到数据库
        // - 触发安全事件
        // - 更新CSP策略
        
        // 返回成功响应
        return reply.status(200).send();
      } else {
        this.logger.error('无效的CSP违规报告格式', request.body);
        return reply.status(400).send({ error: 'Invalid CSP report format' });
      }
    } catch (error) {
      this.logger.error('处理CSP违规报告时出错', error);
      return reply.status(500).send({ error: 'Internal server error' });
    }
  }
}
